﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeGenerator.CSharp
{
    /// <summary>
    /// Defines a parameter that passes information to/from a method.
    /// </summary>
    public class Parameter
    {
        #region Constructors
        public Parameter(string name, string dataType) : this(name, dataType, string.Empty, PassedBy.Value) { }
        public Parameter(string name, string dataType, string description) : this(name, dataType, PassedBy.Value) { }
        public Parameter(string name, string dataType, PassedBy passedBy) : this(name, dataType, string.Empty, passedBy) { }
        public Parameter(string name, string dataType, string description, PassedBy passedBy)
        {
            this.Name = name;
            this.DataType = dataType;
            this.Description = description;
            this.PassedBy = passedBy;
            this.IsExtensionParameter = false;
        } 
        #endregion

        public string Name { get; set; }
        public string DataType { get; set; }
        public string Description { get; set; }
        public PassedBy PassedBy { get; set; }
        public bool IsExtensionParameter { get; set; }

        public override string ToString()
        {
			return string.Format("{0}{1}{2} {3}", this.IsExtensionParameterAsString(), this.PassedByAsString(), DataType, this.Name).TrimStart();
        }

        private string PassedByAsString()
        {
            if (this.PassedBy == CodeGenerator.CSharp.PassedBy.Reference)
                return "ref ";
            
            else if (this.PassedBy == CodeGenerator.CSharp.PassedBy.Out)
                return "out ";

            else
                return "";
        }

        private string IsExtensionParameterAsString()
        {
            if (this.IsExtensionParameter)
                return "this ";

            else
                return "";
        }

    }

    /// <summary>
    /// Defines a collection of parameters.
    /// </summary>
    public class ParameterCollection : List<Parameter>
    {

        public Parameter Add(string name, string dataType) 
        { 
            return this.Add(name, dataType, string.Empty, PassedBy.Value); 
        }

        public Parameter Add(string name, string dataType, string description) 
        { 
            return this.Add(name, dataType, description, PassedBy.Value); 
        }
        
        public Parameter Add(string name, string dataType, PassedBy passedBy) 
        {
            return this.Add(name, dataType, string.Empty, passedBy); 
        }

        public Parameter Add(string name, string dataType, string description, PassedBy passedBy)
        {
            Parameter ThisParameter = new Parameter(name, dataType, description, passedBy);
            this.Add(ThisParameter);
            return ThisParameter;
        }

        public override string ToString()
        {
            CodeBuilder Code = new CodeBuilder();
            foreach (Parameter ThisParameter in this)
            {
                if (Code.Length > 0) Code.Append(", ");
                Code.Append(ThisParameter.ToString());
            }
            return Code.ToString();
        }

    }


    /// <summary>
    /// Identifies the way a parameter can be passed into and out of a method.
    /// </summary>
    public enum PassedBy { Value, Reference, Out }

}
